//+------------------------------------------------------------------+
//|                   DXVertexBuffer.mqh DirectX 缓冲类头文件        |
//|                版权所有 2000-2025, MetaQuotes Ltd.              |
//|                        官方网址: https://www.mql5.com            |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."  // 版权声明
#property link      "https://www.mql5.com"                 // 官方链接

#include "DXHandle.h"  // 引入 DirectX 句柄基类 CDXHandleShared（提供句柄管理基础功能）

//+------------------------------------------------------------------+
//| CDXVertexBuffer 类                                               |
//| 功能：DirectX 顶点缓冲区管理类，负责 3D 模型顶点数据的 GPU 存储与渲染 |
//| 继承关系：public CDXHandleShared（基于共享句柄类，管理 DirectX 资源句柄）|
//| 核心特性：                                                      |
//|  1. 模板化接口支持任意顶点格式（需符合 DirectX 顶点布局规范）      |
//|  2. 封装顶点缓冲区的创建、渲染绑定与资源释放流程                  |
//|  3. 与 DirectX 上下文绑定，确保顶点数据在正确的渲染环境中使用      |
//+------------------------------------------------------------------+
class CDXVertexBuffer : public CDXHandleShared
  {
public:
   /**
    * @brief 析构函数：销毁顶点缓冲区对象
    * @details 自动调用 Shutdown 释放 DirectX 顶点缓冲区资源，避免内存泄漏
    */
   virtual          ~CDXVertexBuffer(void);

   /**
    * @brief 创建顶点缓冲区（模板方法，支持任意顶点格式）
    * @tparam TVertex 顶点数据类型（需包含位置、颜色、纹理坐标等顶点属性，符合渲染管线要求）
    * @param context_handle [in] DirectX 上下文句柄（指定渲染环境，由 DXCreateContext 创建）
    * @param vertices [in] 顶点数据数组（存储待上传至 GPU 的顶点数据）
    * @param start [in] 数组起始索引（从该位置开始读取顶点数据，默认 0）
    * @param count [in] 顶点数量（需上传的顶点总数，默认 WHOLE_ARRAY 表示使用整个数组）
    * @return bool - 操作结果：true 表示缓冲区创建成功（数据已上传至 GPU），false 表示失败（如上下文无效）
    * @note 调用前会自动释放当前持有的缓冲区资源，新创建的缓冲区句柄存储在 m_handle 中
    */
   template<typename TVertex>
   bool              Create(int context_handle,const TVertex &vertices[],uint start=0,uint count=WHOLE_ARRAY);

   /**
    * @brief 将顶点缓冲区绑定到渲染管线（用于绘制）
    * @param start [in] 起始顶点索引（从该位置开始渲染，默认 0）
    * @param count [in] 渲染顶点数量（需绘制的顶点总数，默认 WHOLE_ARRAY 表示使用整个缓冲区）
    * @return bool - 操作结果：true 表示绑定成功（GPU 已准备好使用该缓冲区数据），false 表示失败（如句柄无效）
    * @note 需在绘制前调用，与索引缓冲区配合使用时需确保顶点索引对应正确
    */
   bool              Render(uint start=0,uint count=WHOLE_ARRAY);

   /**
    * @brief 释放顶点缓冲区资源
    * @details 销毁 DirectX 顶点缓冲区句柄（m_handle），释放 GPU 内存，调用后需重新创建才能使用
    */
   void              Shutdown(void);
  };

//+------------------------------------------------------------------+
//| CDXIndexBuffer 类                                                |
//| 功能：DirectX 索引缓冲区管理类，负责 3D 模型索引数据的 GPU 存储与渲染 |
//| 继承关系：public CDXHandleShared（基于共享句柄类，管理 DirectX 资源句柄）|
//| 核心特性：                                                      |
//|  1. 专门处理 uint 类型索引数据（支持 32 位索引，兼容大型模型）      |
//|  2. 封装索引缓冲区的创建、渲染绑定与资源释放流程                  |
//|  3. 与顶点缓冲区配合使用，通过索引复用顶点数据，减少 GPU 内存占用    |
//+------------------------------------------------------------------+
class CDXIndexBuffer : public CDXHandleShared
  {
public:
   /**
    * @brief 析构函数：销毁索引缓冲区对象
    * @details 自动调用 Shutdown 释放 DirectX 索引缓冲区资源，避免内存泄漏
    */
   virtual          ~CDXIndexBuffer(void);

   /**
    * @brief 创建索引缓冲区
    * @param context_handle [in] DirectX 上下文句柄（指定渲染环境，由 DXCreateContext 创建）
    * @param indices [in] 索引数据数组（uint 类型，存储顶点索引，用于复用顶点数据）
    * @param start [in] 数组起始索引（从该位置开始读取索引数据，默认 0）
    * @param count [in] 索引数量（需上传的索引总数，默认 WHOLE_ARRAY 表示使用整个数组）
    * @return bool - 操作结果：true 表示缓冲区创建成功（数据已上传至 GPU），false 表示失败（如上下文无效）
    * @note 调用前会自动释放当前持有的缓冲区资源，新创建的缓冲区句柄存储在 m_handle 中
    */
   bool              Create(int context_handle,const uint &indices[],uint start=0,uint count=WHOLE_ARRAY);

   /**
    * @brief 将索引缓冲区绑定到渲染管线（用于绘制）
    * @param start [in] 起始索引位置（从该位置开始渲染，默认 0）
    * @param count [in] 渲染索引数量（需绘制的索引总数，默认 WHOLE_ARRAY 表示使用整个缓冲区）
    * @return bool - 操作结果：true 表示绑定成功（GPU 已准备好使用该缓冲区数据），false 表示失败（如句柄无效）
    * @note 需与顶点缓冲区配合使用，索引值需在顶点缓冲区的有效范围内（0 ≤ 索引 < 顶点总数）
    */
   bool              Render(uint start=0,uint count=WHOLE_ARRAY);

   /**
    * @brief 释放索引缓冲区资源
    * @details 销毁 DirectX 索引缓冲区句柄（m_handle），释放 GPU 内存，调用后需重新创建才能使用
    */
   void              Shutdown(void);
  };
//+------------------------------------------------------------------+